﻿using System;
using System.Globalization;
using System.Xml.Linq;
using FarseerPhysics.Dynamics;
using IcicleFramework;
using IcicleFramework.Components.Physics;
using Microsoft.Xna.Framework;

namespace ExampleGame.Components.Physics
{
    /// <summary>
    /// We just have a little bit of extra work to do in order to make the ball
    /// function smoother since we're using a physics engine to handle its movement.
    /// Mainly, we don't want it sliding against a wall and never moving diagonally.
    /// </summary>
    public class BallPhysicsComponent : SingleBodyPhysicsComponent
    {
        public float ZeroVelocityTimeAllowed { get; set; }

        public float TimeWithZeroXVelocity { get; protected set; }

        public float TimeWithZeroYVelocity { get; protected set; }

        public float HelperImpulse { get; set; }

        public override void Initialize()
        {
            base.Initialize();

            primaryBody = GetPrimaryBody();
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            //Now, if our velocity along one dimension is zero, keep track of how long it's
            //been like this for...
            if (primaryBody != null)
            {
                float xVel = Math.Abs(primaryBody.LinearVelocity.X);
                float yVel = Math.Abs(primaryBody.LinearVelocity.Y);

                if (xVel < 0.1f)
                    TimeWithZeroXVelocity += (float)gameTime.ElapsedGameTime.TotalSeconds;
                else
                    TimeWithZeroXVelocity = 0f;

                if (yVel < 0.1f)
                    TimeWithZeroYVelocity += (float)gameTime.ElapsedGameTime.TotalSeconds;
                else
                    TimeWithZeroYVelocity = 0f;
            }
            
            //Give it an impulse!
            if (TimeWithZeroXVelocity > ZeroVelocityTimeAllowed)
            {
                primaryBody.ApplyLinearImpulse(new Vector2(HelperImpulse, 0f));
                TimeWithZeroXVelocity = 0f;
            }

            if (TimeWithZeroYVelocity > ZeroVelocityTimeAllowed)
            {
                primaryBody.ApplyLinearImpulse(new Vector2(0f, HelperImpulse));
                TimeWithZeroYVelocity = 0f;
            }
        }

        public override void Deserialize(XElement element)
        {
            float zeroVelocityTime = float.PositiveInfinity;
            if (element.Element("zeroVelocityTime") != null)
                float.TryParse(element.Element("zeroVelocityTime").Value, NumberStyles.Float, CultureInfo.InvariantCulture, out zeroVelocityTime);
            ZeroVelocityTimeAllowed = zeroVelocityTime;

            float helperImpulse = 0f;
            if (element.Element("helperImpulse") != null)
                float.TryParse(element.Element("helperImpulse").Value, NumberStyles.Float, CultureInfo.InvariantCulture, out helperImpulse);
            HelperImpulse = ConvertUnits.ToSimUnits(helperImpulse);


            base.Deserialize(element);
        }
    }
}
